package org.infodavid.common.services;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;

import org.joda.time.DateTime;
import org.junit.Test;

import org.infodavid.common.dto.IUserListItem;
import org.infodavid.common.dto.IUserGroupListItem.EUserRole;
import org.infodavid.common.impl.model.criteria.UserCriteriaImpl;
import org.infodavid.common.impl.services.UserServiceImpl;
import org.infodavid.common.model.AbstractBeanTest;
import org.infodavid.common.model.IUser;
import org.infodavid.common.model.IUserGroup;
import org.infodavid.common.model.IUserSession;
import org.infodavid.common.model.UserTest;
import org.infodavid.common.model.criteria.IUserCriteria;
import org.infodavid.common.persistence.UserDataService;
import org.infodavid.common.persistence.UserGroupDataService;
import org.infodavid.common.persistence.UserSessionDataService;
import org.infodavid.common.services.UserService;
import org.infodavid.common.services.exception.AccessDeniedException;
import org.infodavid.common.services.exception.UserAccountExpiredException;
import org.infodavid.common.services.exception.UserAccountLockedException;

/**
 * The Class UserServiceTest.
 */
@SuppressWarnings({
	"null"
})
public class UserServiceTest extends
    AbstractServiceTest<IUserListItem,IUser,IUserCriteria,UserDataService> {

	/** The delegate. */
	private final UserTest delegate = new UserTest(this);

	/**
	 * The Constructor.
	 */
	public UserServiceTest() {
		super(UserService.getInstance());
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.services.AbstractServiceTest#setUp()
	 */
	@Override
	public void setUp() throws Exception {
		super.setUp();

		UserServiceImpl.session = getSession();
	}

	/**
	 * See super class or interface. (non-Javadoc)
	 * @return the data service class
	 * @see org.infodavid.common.services.AbstractServiceTest#getDataServiceClass()
	 */
	@Override
	public Class<UserDataService> getDataServiceClass() {
		return UserDataService.class;
	}

	/**
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.services.AbstractServiceTest#buildCriteria()
	 */
	@Override
	public IUserCriteria buildCriteria() {
		final IUserCriteria criteria = new UserCriteriaImpl();

		criteria.setNamePattern("name");

		return criteria;
	}

	/**
	 * Test find by name.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByName() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByName(getContextMock(), value.getName());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", value);
		Assert.assertNotNull("Key is null", value.getKey());
	}

	/**
	 * Test find by name.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByEmail() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByEmail(getContextMock(), value.getEmail().getValue());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", value);
		Assert.assertNotNull("Key is null", value.getKey());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByEmailUsingAnInvalidContext() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();

		try {
			((UserService)getService()).findByEmail(null, value.getEmail().getValue());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByEmailWithoutValue() throws Exception {
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByEmail(getContextMock(), null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test find by name.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByGroup() throws Exception {
		final List<IUserListItem> results = new ArrayList<IUserListItem>();
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByGroup(getContextMock(), value.getPrimaryGroup().getKey(),
			    results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", value);
		Assert.assertNotNull("Key is null", value.getKey());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByGroupUsingAnInvalidContext() throws Exception {
		final List<IUserListItem> results = new ArrayList<IUserListItem>();
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();

		try {
			((UserService)getService())
			    .findByGroup(null, value.getPrimaryGroup().getKey(), results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByGroupWithoutValue() throws Exception {
		final List<IUserListItem> results = new ArrayList<IUserListItem>();
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByGroup(getContextMock(), null, results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByNameWithoutValue() throws Exception {
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByName(getContextMock(), null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByNameUsingAnInvalidContext() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();

		try {
			((UserService)getService()).findByName(null, value.getName());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test add.
	 * @throws Exception the exception
	 */
	@Test
	public final void testAddWithoutName() throws Exception {
		final IUser value = create(1).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		value.setName(null);

		try {
			getService().add(getContextMock(), value);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test find by name.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByRole() throws Exception {
		final List<IUser> results = new ArrayList<IUser>();
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByRole(getContextMock(), value.getPrimaryGroup().getRole(),
			    results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", value);
		Assert.assertNotNull("Key is null", value.getKey());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByRoleUsingAnInvalidContext() throws Exception {
		final List<IUser> results = new ArrayList<IUser>();
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();

		try {
			((UserService)getService())
			    .findByRole(null, value.getPrimaryGroup().getRole(), results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindByRoleWithoutValue() throws Exception {
		final List<IUser> results = new ArrayList<IUser>();
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findByRole(getContextMock(), null, results, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test find by name.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindRoles() throws Exception {
		final List<EUserRole> results = new ArrayList<EUserRole>();
		final IUser value = populate(ITEMS_TO_INSERT).get(0);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findRoles(getContextMock(), value.getKey(), results);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", value);
		Assert.assertNotNull("Key is null", value.getKey());
	}

	/**
	 * Test testFindByName.
	 * @throws Exception the exception
	 */
	@Test
	public final void testFindRolesWithoutValue() throws Exception {
		final List<EUserRole> results = new ArrayList<EUserRole>();
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).findRoles(getContextMock(), null, results);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignIn() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", result);
		Assert.assertNotNull("User is null", result.getUser());
		Assert.assertNotNull("User session is null", result.getUserSession());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInSessionExpired() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
			UserSessionDataService.getInstance().remove(getSession(), result.getUserSession().getKey());
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", result);
		Assert.assertNotNull("User is null", result.getUser());
		Assert.assertNotNull("User session is null", result.getUserSession());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInAfterSignOut() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
			((UserService)getService()).signOut(result);
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", result);
		Assert.assertNotNull("User is null", result.getUser());
		Assert.assertNotNull("User session is null", result.getUserSession());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignOut() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
			((UserService)getService()).signOut(result);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignOutTwice() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
			((UserService)getService()).signOut(result);
			((UserService)getService()).signOut(result);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInTwice() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		IApplicationContext result = null;
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user can signin
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", result);
		Assert.assertNotNull("User is null", result.getUser());

		IUserSession session = result.getUserSession();
		Assert.assertNotNull("User session is null", session);

		Thread.sleep(50);

		try {
			result = ((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);
		Assert.assertNotNull("Data is null", result);
		Assert.assertNotNull("User is null", result.getUser());
		Assert.assertNotNull("User session is null", result.getUserSession());
		Assert.assertEquals("Session not reused", session, result.getUserSession());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInExpired() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().minusMinutes(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", UserAccountExpiredException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInLocked() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(true);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", UserAccountLockedException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInWrongName() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, "wrong" + value.getLoginName(), value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", AccessDeniedException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInNullName() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, null, value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInWrongPassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, value.getLoginName(), "wrong" + value.getPassword());
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", AccessDeniedException.class, exception.getClass());
	}

	/**
	 * Test testSignIn.
	 * @throws Exception the exception
	 */
	@Test
	public final void testSignInNullPassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		// system role can not invoke the signin
		for (IUserGroup item : value.getGroups().values()) {
			if (item.getRole() == EUserRole.SYSTEM) {
				item.setRole(EUserRole.NORMAL);
				UserGroupDataService.getInstance().update(getSession(), item);
			}
		}

		// ensure user is expired
		value.setExpirationDate(new DateTime().plusYears(1));
		value.setArchived(false);
		value.setLocked(false);

		UserDataService.getInstance().update(getSession(), value);

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).signIn(null, value.getLoginName(), null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test.
	 * @throws Exception the exception
	 */
	@Test
	public final void testChangePasswordNullPassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).changePassword(getContextMock(), value.getKey(), null, null);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test.
	 * @throws Exception the exception
	 */
	@Test
	public final void testChangePasswordUsingWrongPassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).changePassword(getContextMock(), value.getKey(),
			    value.getPassword() + "0", "123456");
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", AccessDeniedException.class, exception.getClass());
	}

	/**
	 * Test.
	 * @throws Exception the exception
	 */
	@Test
	public final void testChangePasswordUsingInvalidPassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).changePassword(getContextMock(), value.getKey(),
			    value.getPassword(), value.getPassword() + '\'');
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNotNull("An exception occurs", exception);
		Assert.assertEquals("Wrong exception", IllegalArgumentException.class, exception.getClass());
	}

	/**
	 * Test.
	 * @throws Exception the exception
	 */
	@Test
	public final void testChangePassword() throws Exception {
		final IUser value = populate(ITEMS_TO_INSERT).get(ITEMS_TO_INSERT - 1);
		Exception exception = null;
		String newPassword = "123456";

		expectationsOnPersistenceSession();
		expectationsOnSecureService();

		try {
			((UserService)getService()).changePassword(getContextMock(), value.getKey(),
			    value.getPassword(), newPassword);
		}
		catch (final Exception e) {
			e.printStackTrace();
			exception = e;
		}

		Assert.assertNull("An exception occurs", exception);

		IUser modified = UserDataService.getInstance().findByPrimaryKey(getSession(), value.getKey());

		Assert.assertEquals("Password not persisted", newPassword, modified.getPassword());
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.persistence.AbstractDataServiceTest#getBeanTest()
	 */
	@Override
	protected AbstractBeanTest<IUser> getBeanTest() {
		return delegate;
	}
}
